package com.linwb.mytools;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 
 * Title: LWB <br>
 * Project Name: BatchMavenUpload <br>
 * Description: 批量Maven上传语句生成 <br>
 * 只需要设置2个目录，1个是jar包所在的路径即dir，另外一个是prefix，即jar包非包名的部分，
 * 例如 1. dir  F:\\import\\com\\ai\\ecpcore\\ecp-web-mall-jar\\1.10.1-RELEASE   prefix 就是  F:\\import
 * 例如 2. dir  E:\\jarimport\\xmlenc\\xmlenc\\0.52   prefix 就是  E:\\jarimport
 * 
 * 还需要设置 repositoryIds repositoryURLs 为pom或setting上配置的id和url
 * 
 * 另外需要注意：要导入jar的路径必须符合maven的路径规则，如果从本地仓库拷贝出来，那么不需要关注这点，否需要需要关注这个路径规则，
 * 完整的路径规则例如：
 * 1.F:\\import\\com\\ai\\ecpcore\\ecp-web-mall-jar\\1.10.1-RELEASE
 * 即扣除prfix(F:\\import)后，路径的规则是     groupId\\artifactId\\version
 * 
 * 
 * 2.E:\\jarimport\\xmlenc\\xmlenc\\0.52
 * 即扣除prfix(E:\\jarimport)后，路径的规则是     groupId\\artifactId\\version
 * 
 * PS:1.需要注意，如果jar的路径是本地maven的lib目录，可能会导致上传不去，所以需要另外创建目录
 * PS:2.需要注意，不支持classifier版本
 * @author linwb3
 * @version
 * @since JDK 1.6
 */
public class BathUploadJarToNexus {
	
	
	private static String prefix = "F:\\import";
	private static String dir = "F:\\import\\com";
	private static String[] types = new String[] { "jar", "pom" };
	private static String[] repositoryIds = new String[] { "releases", "snapshots" };
	private static String[] repositoryURLs = new String[] { "http://114.55.224.37:8081/repository/txk-release/", "http://114.55.224.37:8081/repository/txk-snapshot/" };
	private static String VERSION_RELEASE="RELEASE";
	private static String VERSION_SNAPSHOT="SNAPSHOT";
	private static String cmd = "mvn deploy:deploy-file -DgroupId={group} -DartifactId={name} " 
	+" -Dversion={version}"  
	+" -Dpackaging={type}  " 
	+" -Dfile={dir}"  
	+" -Durl={repositoryURL}" 
	+" -DpomFile={dpomFile}" 
	+" -DrepositoryId={repositoryId}";
	
	public static void main(String[] args) {
		
		List<FileName> names = getFileNameEndWithJarOrPom(null,null);
		List<Maven> mavens = analysis(names);
		for (Maven maven : mavens) {
			String mavenCMD = getMavenCMD(maven);
			executeCMD(mavenCMD);
			BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(5000);
			ThreadPoolExecutor pool = new ThreadPoolExecutor(4, 4, 1, TimeUnit.HOURS, queue, new ThreadPoolExecutor.CallerRunsPolicy());
			pool.execute(new DoMavenThread(mavenCMD));
		}
		try {
			Thread.currentThread().sleep(100000000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private static String getMavenCMD(Maven maven) {
		int index=0;
		if(VERSION_SNAPSHOT.equals(maven.getVersionType())){
			index=1;
		}
		String rs=cmd.replace("{group}", maven.getGroupId())
				.replace("{dir}", maven.getDir())
				.replace("{version}", maven.getVersion())
				.replace("{name}", maven.getArtifactId())
				.replace("{type}", maven.getType())
				.replace("{repositoryURL}", repositoryURLs[index])
				.replace("{repositoryId}", repositoryIds[index]);
		if(maven.getPomFile()!=null && !"".equals(maven.getPomFile().trim())){
			return rs.replace("{dpomFile}", maven.getPomFile());
		}else{
			return rs.replace("-DpomFile={dpomFile}", " ");
		}
		 
	}

	private static void executeCMD(String command) {
		String line = null;
		StringBuilder sb = new StringBuilder();
		Runtime runtime = Runtime.getRuntime();
		BufferedReader bufferedReader = null;
		try {
			System.out.println();
			System.out.println("----------�?始执行CMD命令----------");
			System.out.println("----------�?始执行CMD命令:"+command);
			System.out.println();
			Process process = runtime.exec("cmd /c "+command);
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
			while ((line = bufferedReader.readLine()) != null) {
				sb.append(line + "\n");
				System.out.println(line);
			}
			System.out.println();
			System.out.println("----------结束执行CMD命令----------");
			System.out.println();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static String SPILT = "\\";

	public static List<Maven> analysis(List<FileName> names) {
		List<Maven> mavens = new ArrayList<Maven>();
		List<String> dirs = new ArrayList<String>();
		for (FileName name : names) {
			String[] arr = name.getFileName().split(SPILT + SPILT);
			String fileName = arr[arr.length - 1];
			String[] fileNameSub = fileName.split("\\.");
			String type = fileNameSub[fileNameSub.length - 1];
			String version = arr[arr.length - 2];
			String artifactId = arr[arr.length - 3];
			String groupId = name.getFileName().replace(SPILT + artifactId + SPILT + version + SPILT + fileName, "").replace(prefix, "").replace(SPILT, ".");
			if(groupId.startsWith(".")){
				groupId=groupId.substring(1, groupId.length());
			}
			String dir = name.getFileName().replace(fileName, artifactId + "-" + version + "." + type);
			if(!fileName.contains(version)){
				continue;
			}
			if (dirs.contains(dir)) {
				continue;
			} else {
				dirs.add(dir);
			}
			String versionType="";
			if(version.contains(VERSION_SNAPSHOT)){
				versionType=VERSION_SNAPSHOT;
			}else if(version.contains(VERSION_RELEASE)){
				versionType=VERSION_RELEASE;
			}else{
				versionType=VERSION_RELEASE;
			}
			Maven maven = new Maven(groupId, artifactId, version, dir, type,versionType,name.getPomFile());
			mavens.add(maven);
		}
		return mavens;
	};

	public static List<FileName> getFileNameEndWithJarOrPom(String path,String pom) {
		List<FileName> files = new ArrayList<FileName>();
		File parent = new File(path == null ? dir : path);
		String name = parent.getName();
		String type = getType(name);
		if (parent.isDirectory()) {
			File[] sons = parent.listFiles();
			String jarFile=null;
			String pomFile=null;
			for (File son : sons) {
				if(son.isDirectory()){
					files.addAll(getFileNameEndWithJarOrPom(son.getPath(),null));
					continue;
				}
				String[] arr = son.getPath().split(SPILT + SPILT);
				String fileName = arr[arr.length - 1];
				String version = arr[arr.length - 2];
				if(!fileName.contains(version)){
					continue;
				}
				String sonType = getType(son.getName());
				if ("jar".equals(sonType)) {
					jarFile=son.getPath();
				}
				if ("pom".equals(sonType)) {
					pomFile=son.getPath();
				}
			}
			if(jarFile!=null){
				files.addAll(getFileNameEndWithJarOrPom(jarFile,pomFile));
			}else if(pomFile!=null){
				files.addAll(getFileNameEndWithJarOrPom(pomFile,null));
			}
			
		} else if (type != null) {
			FileName fileName=new FileName(parent.getPath(), pom);
			files.add(fileName);
		}
		return files;
	}

	private static String getType(String name) {
		for (String type : types) {
			if (name != null && name.endsWith(type)) {
				return type;
			}
		}
		return null;
	}
	
	static class FileName {
		private String fileName;
		private String pomFile;
		
		public FileName(String fileName, String pomFile) {
			this.fileName = fileName;
			this.pomFile = pomFile;
		}

		public String getFileName() {
			return fileName;
		}

		public void setFileName(String fileName) {
			this.fileName = fileName;
		}

		public String getPomFile() {
			return pomFile;
		}

		public void setPomFile(String pomFile) {
			this.pomFile = pomFile;
		}
	}

	static class Maven {
		private String groupId;
		private String artifactId;
		private String version;
		private String dir;
		private String type;
		private String versionType;
		private String pomFile;

		public Maven(String groupId, String artifactId, String version, String dir, String type,String versionType,String pomFile) {
			this.groupId = groupId;
			this.artifactId = artifactId;
			this.version = version;
			this.dir = dir;
			this.type = type;
			this.versionType = versionType;
			this.pomFile = pomFile;
			
		}

		public String getGroupId() {
			return groupId;
		}

		public void setGroupId(String groupId) {
			this.groupId = groupId;
		}

		public String getArtifactId() {
			return artifactId;
		}

		public void setArtifactId(String artifactId) {
			this.artifactId = artifactId;
		}

		public String getVersion() {
			return version;
		}

		public void setVersion(String version) {
			this.version = version;
		}

		public String getDir() {
			return dir;
		}

		public void setDir(String dir) {
			this.dir = dir;
		}

		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

		public String getVersionType() {
			return versionType;
		}

		public void setVersionType(String versionType) {
			this.versionType = versionType;
		}

		public String getPomFile() {
			return pomFile;
		}

		public void setPomFile(String pomFile) {
			this.pomFile = pomFile;
		}
	}
	
	private static class DoMavenThread implements Runnable {
		private String cmd;

		public DoMavenThread(String cmd) {
			this.cmd = cmd;
		}
		public void run() {
			executeCMD(cmd);
		}
	}
}
